package org.dh2580.netty.demo.netty.protocol.privately;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSON;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.util.CharsetUtil;

/**
 * @Author: hao.deng
 * @Date: 2019/5/8-下午5:39
 */
public class NettyMessageDecoder extends ByteToMessageDecoder {

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {

        NettyMessage message = new NettyMessage();

        NettyHeader header = new NettyHeader();
        header.setCrcCode(in.readInt());
        header.setLength(in.readInt());
        header.setSessionId(in.readLong());
        header.setType(in.readByte());
        header.setPriority(in.readByte());

        int size = in.readInt();
        if (size > 0) {
            Map<String, String> attach = new HashMap<>(size);

            String key = null;
            byte[] keyArray = null;

            int keySize = 0;

            String value = null;
            byte[] valueArray = null;

            int valueSize = 0;

            for (int i = 0; i < size; i++) {
                keySize = in.readInt();
                keyArray = new byte[keySize];
                in.readBytes(keyArray);
                key = new String(keyArray, CharsetUtil.UTF_8);

                valueSize = in.readInt();
                valueArray = new byte[valueSize];
                in.readBytes(valueArray);
                value = new String(valueArray, CharsetUtil.UTF_8);

                attach.put(key, value);
            }

            header.setAttachment(attach);
        }

        boolean hasBody = in.readBoolean();
        if (hasBody) {
            int clazzLen = in.readInt();
            byte[] clazzBytes = new byte[clazzLen];
            in.readBytes(clazzBytes);
            Class clazz = Class.forName(new String(clazzBytes, CharsetUtil.UTF_8));

            int bodyLen = in.readInt();
            byte[] bodyBytes = new byte[bodyLen];
            in.readBytes(bodyBytes);

            Object body = JSON.parseObject(new String(bodyBytes, CharsetUtil.UTF_8), clazz);
            message.setBody(body);
        }

        message.setHeader(header);

        out.add(message);
    }
}
